package com.winchain.chainbill.bill.biz.contract.cmd;

import com.shell.bee.base.exception.UnCheckMsgException;
import com.shell.bee.cfca.paperless.request.CfcaSignRequest;
import com.shell.bee.cfca.paperless.response.BaseResponse;
import com.shell.bee.cfca.paperless.service.CfcaSignTxService;
import com.shell.bee.contract.ContService;
import com.shell.bee.contract.po.ContBas;
import com.shell.bee.contract.po.ContProt;
import com.shell.bee.contract.po.ContTmpl;
import com.shell.bee.esign.po.EsCust;
import com.shell.bee.esign.service.EsCustService;
import com.shell.bee.esign.service.EsignSealService;
import com.shell.bee.esign.service.EsignSignService;
import com.shell.bee.esign.vo.SingleSignVo;
import com.shell.bee.report.utils.PdfUtils;
import com.shell.feign.PubUserFeign;
import com.shell.framework.command.CommandContext;
import com.shell.framework.command.ICommand;
import com.shell.framework.utils.CommonDataUtil;
import com.shell.governor.user.po.PubUser;
import com.timevale.esign.sdk.tech.bean.result.AddSealResult;
import com.timevale.esign.sdk.tech.bean.result.FileDigestSignResult;
import com.timevale.esign.sdk.tech.bean.seal.OrganizeTemplateType;
import com.timevale.esign.sdk.tech.bean.seal.PersonTemplateType;
import com.timevale.esign.sdk.tech.bean.seal.SealColor;
import com.winchain.chainbill.ChainBillUtil;
import com.winchain.chainbill.basic.cus.po.CusRec;
import com.winchain.chainbill.basic.cus.service.CusRecService;
import com.winchain.chainbill.bill.base.po.CbDct;
import com.winchain.chainbill.bill.base.po.CbRec;
import com.winchain.chainbill.bill.base.po.CbSnd;
import com.winchain.chainbill.bill.base.po.CbXfe;
import com.winchain.chainbill.bill.biz.Bill;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class ContractSignCmd<T> implements ICommand<Bill<T>> {
	@Autowired
	private ContService contService;
	@Autowired
	private EsignSignService esignSignService;
	@Autowired
	private EsCustService esCustService;
	@Autowired
	private CusRecService cusRecService;
	@Autowired
	private EsignSealService esignSealService;
	@Autowired
	private PubUserFeign pubUserFeign;
	@Autowired
	private CfcaSignTxService cfcaSignTxService;

	public boolean execute(CommandContext<Bill<T>> context) throws Exception {
		CbRec bill = ((Bill) context.getSource()).getRec();
		T source = (T) ((Bill) context.getSource()).getSource();
		String bizType = null;
		String billId = bill.getBillId();
		String reason = null;
		if ((source instanceof CbSnd)) {
			bizType = "10";
			reason = "������������";
		} else if ((source instanceof CbXfe)) {
			bizType = "11";
			reason = "������������";
		} else if ((source instanceof CbDct)) {
			bizType = "12";
			reason = "������������";
			Object children = context.getValue("children");
			if (children != null) {
				List<Bill<CbDct>> bills = (List) children;
				for (Bill<CbDct> dctBill : bills) {
					CbDct dct = (CbDct) dctBill.getSource();
					if ((dct != null) && (dct.getDctId() != null)) {
						billId = dct.getBillId();
						break;
					}
				}
			}
		}
		String custId = CommonDataUtil.getCurEntId();
		ContBas cont = this.contService.getLatestCont(custId, billId, bizType, null);
		if (cont != null) {
			String sealCode = context.getStringValue("sealCode");
			String phoneCode = context.getStringValue("phoneCode");
			if (ChainBillUtil.onEsign()) {
				sign(cont, phoneCode, bizType);
			} else if (ChainBillUtil.onCfca()) {
				String location = context.getStringValue("location");
				signCfca(cont, phoneCode, bizType, location, reason, sealCode);
			}
			boolean finished = false;
			if (!custId.equals(cont.getSponsor())) {
				if ("10".equals(cont.getBizType())) {
					Object isNotNeedAprv = context.getValue("isNotNeedAprv");
					if ((isNotNeedAprv != null) && (((Boolean) isNotNeedAprv).booleanValue())) {
						if (custId.equals(cont.getAcceptor())) {
							finished = true;
						}
					} else if (custId.equals(cont.getWitness())) {
						finished = true;
					}
				} else if (custId.equals(cont.getAcceptor())) {
					finished = true;
				}
			}
			if (finished) {
				cont.setContProgress("1");
			}
			this.contService.sign(cont, custId);
		}
		return false;
	}

	private void signCfca(ContBas cont, String phoneCode, String bizType, String location, String reason,
			String sealCode) {
		String entId = CommonDataUtil.getCurEntId();
		PubUser user = this.pubUserFeign.selectByKey(CommonDataUtil.getUserId());
		CusRec curCus = (CusRec) this.cusRecService.selectByKey(entId);
		ContProt contProt = null;
		ContTmpl contTmpl = null;
		List<ContProt> prots = null;
		prots = this.contService.selectProts(cont.getContId());
		if ((prots != null) && (prots.size() > 0)) {
			contProt = (ContProt) prots.get(0);
			contTmpl = this.contService.selectContTmplByKey(contProt.getTmplId());
		}
		if (contProt == null) {
			throw new UnCheckMsgException("����������");
		}
		CfcaSignRequest request = new CfcaSignRequest();
		request.setUserId(user.getUserId());
		request.setUserName(user.getUserName());
		request.setIdNo(user.getCertNo());
		request.setPhoneNo(user.getPhoneNo());
		request.setPhoneCode(phoneCode);
		request.setCusId(entId);
		request.setCusName(curCus.getCusName());
		request.setLocation(location);
		request.setReason(reason);
		request.setContId(cont.getContId());
		request.setSrcPdfPath(contProt.getProtLoc());
		request.setDestPdfPath(contProt.getProtLoc());
		request.setKey(curCus.getCusName());
		if (entId.equals(cont.getSponsor())) {
			request.setSignPage(Integer.parseInt(contTmpl.getSponsorPage()));
			request.setKeyIndex(contTmpl.getSponsorKeyIndex());
		} else if (entId.equals(cont.getAcceptor())) {
			request.setSignPage(Integer.parseInt(contTmpl.getAcceptorPage()));
			request.setKeyIndex(contTmpl.getAcceptorKeyIndex());
		} else {
			request.setSignPage(Integer.parseInt(contTmpl.getWitnessPage()));
			request.setKeyIndex(contTmpl.getWitnessKeyIndex());
		}
		request.setSealCode(sealCode);
		BaseResponse response = this.cfcaSignTxService.sign(request);
		if (!response.isSuccess()) {
			throw new UnCheckMsgException("��������������cfca��" + response.getMessage());
		}
	}

	private FileDigestSignResult sign(ContBas cont, String phoneCode, String bizType) {
		String entId = CommonDataUtil.getCurEntId();
		PubUser user = this.pubUserFeign.selectByKey(CommonDataUtil.getUserId());
		CusRec curCus = (CusRec) this.cusRecService.selectByKey(entId);

		AddSealResult seal = null;
		EsCust esCust;
		if ("PERSONAL".equals(curCus.getCusType())) {
			esCust = (EsCust) this.esCustService.selectByKey(CommonDataUtil.getUserId());
			seal = this.esignSealService.getPersonSeal(esCust.getAcctId(), PersonTemplateType.RECTANGLE, SealColor.RED);
		} else {
			esCust = (EsCust) this.esCustService.selectByKey(entId);
			seal = this.esignSealService.getOrganizeSeal(esCust.getAcctId(), OrganizeTemplateType.STAR, SealColor.RED,
					"", "");
		}
		ContProt contProt = null;
		List<ContProt> prots = null;
		prots = this.contService.selectProts(cont.getContId());
		if ((prots != null) && (prots.size() > 0)) {
			contProt = (ContProt) prots.get(0);
		}
		if (contProt == null) {
			throw new UnCheckMsgException("����������");
		}
		Map<String, String> positon = PdfUtils.getKeyFirstPosition(contProt.getProtLoc(), esCust.getCustNm());
		if (positon.size() == 0) {
			throw new UnCheckMsgException("������������");
		}
		SingleSignVo singleSignVo = new SingleSignVo();
		singleSignVo.setContId(cont.getContId());
		singleSignVo.setAcctId(esCust.getAcctId());
		singleSignVo.setSrcPdfPath(contProt.getProtLoc());
		singleSignVo.setDestPdfPath(contProt.getProtLoc());
		singleSignVo.setSignPage((String) positon.get("page"));
		singleSignVo.setX((String) positon.get("X"));
		singleSignVo.setY((String) positon.get("Y"));
		singleSignVo.setSealData(seal.getSealData());
		singleSignVo.setPhoneNo(user.getPhoneNo());
		singleSignVo.setPhoneCode(phoneCode);
		FileDigestSignResult result = this.esignSignService.sign(singleSignVo);
		if (result.getErrCode() != 0) {
			throw new UnCheckMsgException("��������������e����" + result.getMsg());
		}
		return result;
	}
}
